import chroma from 'chroma-js';
import { Color, RGB, HSL, HSV } from '@/types';

/**
 * 色彩工具类 - 处理色彩转换、计算和操作
 */
export class ColorUtils {
  
  /**
   * 创建Color对象从十六进制值
   */
  static fromHex(hex: string): Color {
    const chromaColor = chroma(hex);
    return {
      hex: chromaColor.hex(),
      rgb: this.rgbFromChroma(chromaColor),
      hsl: this.hslFromChroma(chromaColor),
      hsv: this.hsvFromChroma(chromaColor),
      createdAt: new Date()
    };
  }

  /**
   * 创建Color对象从RGB值
   */
  static fromRgb(r: number, g: number, b: number): Color {
    const chromaColor = chroma.rgb(r, g, b);
    return {
      hex: chromaColor.hex(),
      rgb: { r, g, b },
      hsl: this.hslFromChroma(chromaColor),
      hsv: this.hsvFromChroma(chromaColor),
      createdAt: new Date()
    };
  }

  /**
   * 创建Color对象从HSL值
   */
  static fromHsl(h: number, s: number, l: number): Color {
    const chromaColor = chroma.hsl(h, s / 100, l / 100);
    return {
      hex: chromaColor.hex(),
      rgb: this.rgbFromChroma(chromaColor),
      hsl: { h, s, l },
      hsv: this.hsvFromChroma(chromaColor),
      createdAt: new Date()
    };
  }

  /**
   * 创建Color对象从HSV值
   */
  static fromHsv(h: number, s: number, v: number): Color {
    const chromaColor = chroma.hsv(h, s / 100, v / 100);
    return {
      hex: chromaColor.hex(),
      rgb: this.rgbFromChroma(chromaColor),
      hsl: this.hslFromChroma(chromaColor),
      hsv: { h, s, v },
      createdAt: new Date()
    };
  }

  /**
   * 验证十六进制颜色格式
   */
  static isValidHex(hex: string): boolean {
    return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex);
  }

  /**
   * 验证RGB值
   */
  static isValidRgb(r: number, g: number, b: number): boolean {
    return [r, g, b].every(val => val >= 0 && val <= 255 && Number.isInteger(val));
  }

  /**
   * 验证HSL值
   */
  static isValidHsl(h: number, s: number, l: number): boolean {
    return h >= 0 && h <= 360 && s >= 0 && s <= 100 && l >= 0 && l <= 100;
  }

  /**
   * 计算两个颜色之间的对比度
   */
  static getContrast(color1: Color, color2: Color): number {
    return chroma.contrast(color1.hex, color2.hex);
  }

  /**
   * 计算颜色的亮度
   */
  static getLuminance(color: Color): number {
    return chroma(color.hex).luminance();
  }

  /**
   * 判断颜色是否为浅色
   */
  static isLight(color: Color): boolean {
    return this.getLuminance(color) > 0.5;
  }

  /**
   * 判断颜色是否为深色
   */
  static isDark(color: Color): boolean {
    return !this.isLight(color);
  }

  /**
   * 获取颜色的互补色
   */
  static getComplementary(color: Color): Color {
    const hsl = color.hsl;
    const complementaryHue = (hsl.h + 180) % 360;
    return this.fromHsl(complementaryHue, hsl.s, hsl.l);
  }

  /**
   * 获取颜色的类似色（相邻色）
   */
  static getAnalogous(color: Color, count: number = 2): Color[] {
    const hsl = color.hsl;
    const step = 30; // 30度间隔
    const colors: Color[] = [];
    
    for (let i = 1; i <= count; i++) {
      const hue1 = (hsl.h + step * i) % 360;
      const hue2 = (hsl.h - step * i + 360) % 360;
      
      colors.push(this.fromHsl(hue1, hsl.s, hsl.l));
      if (colors.length < count * 2) {
        colors.push(this.fromHsl(hue2, hsl.s, hsl.l));
      }
    }
    
    return colors.slice(0, count);
  }

  /**
   * 获取三元色组合
   */
  static getTriadic(color: Color): Color[] {
    const hsl = color.hsl;
    return [
      this.fromHsl((hsl.h + 120) % 360, hsl.s, hsl.l),
      this.fromHsl((hsl.h + 240) % 360, hsl.s, hsl.l)
    ];
  }

  /**
   * 获取四元色组合
   */
  static getTetradic(color: Color): Color[] {
    const hsl = color.hsl;
    return [
      this.fromHsl((hsl.h + 90) % 360, hsl.s, hsl.l),
      this.fromHsl((hsl.h + 180) % 360, hsl.s, hsl.l),
      this.fromHsl((hsl.h + 270) % 360, hsl.s, hsl.l)
    ];
  }

  /**
   * 获取单色调色板（不同明度的同色相）
   */
  static getMonochromatic(color: Color, count: number = 5): Color[] {
    const hsl = color.hsl;
    const colors: Color[] = [];
    const lightnessDiff = 80 / (count + 1);
    
    for (let i = 1; i <= count; i++) {
      const lightness = Math.max(10, Math.min(90, 10 + lightnessDiff * i));
      colors.push(this.fromHsl(hsl.h, hsl.s, lightness));
    }
    
    return colors;
  }

  /**
   * 调整颜色亮度
   */
  static adjustLightness(color: Color, amount: number): Color {
    const hsl = color.hsl;
    const newLightness = Math.max(0, Math.min(100, hsl.l + amount));
    return this.fromHsl(hsl.h, hsl.s, newLightness);
  }

  /**
   * 调整颜色饱和度
   */
  static adjustSaturation(color: Color, amount: number): Color {
    const hsl = color.hsl;
    const newSaturation = Math.max(0, Math.min(100, hsl.s + amount));
    return this.fromHsl(hsl.h, newSaturation, hsl.l);
  }

  /**
   * 调整颜色色相
   */
  static adjustHue(color: Color, amount: number): Color {
    const hsl = color.hsl;
    const newHue = (hsl.h + amount + 360) % 360;
    return this.fromHsl(newHue, hsl.s, hsl.l);
  }

  /**
   * 混合两个颜色
   */
  static mix(color1: Color, color2: Color, ratio: number = 0.5): Color {
    const mixed = chroma.mix(color1.hex, color2.hex, ratio);
    return this.fromHex(mixed.hex());
  }

  /**
   * 获取颜色的温度感知（暖色/冷色）
   */
  static getTemperature(color: Color): 'warm' | 'cool' | 'neutral' {
    const hue = color.hsl.h;
    
    if ((hue >= 0 && hue <= 60) || (hue >= 300 && hue <= 360)) {
      return 'warm'; // 红、橙、黄
    } else if (hue >= 120 && hue <= 240) {
      return 'cool'; // 绿、青、蓝
    } else {
      return 'neutral'; // 过渡色
    }
  }

  /**
   * 生成随机颜色
   */
  static randomColor(): Color {
    const hue = Math.floor(Math.random() * 360);
    const saturation = Math.floor(Math.random() * 60) + 40; // 40-100%
    const lightness = Math.floor(Math.random() * 60) + 20; // 20-80%
    
    return this.fromHsl(hue, saturation, lightness);
  }

  /**
   * 将颜色转换为CSS字符串
   */
  static toCssString(color: Color, format: 'hex' | 'rgb' | 'hsl' = 'hex'): string {
    switch (format) {
      case 'rgb':
        return `rgb(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b})`;
      case 'hsl':
        return `hsl(${color.hsl.h}, ${color.hsl.s}%, ${color.hsl.l}%)`;
      default:
        return color.hex;
    }
  }

  /**
   * 检查颜色是否符合WCAG可访问性标准
   */
  static checkAccessibility(foreground: Color, background: Color): {
    wcagAA: boolean;
    wcagAAA: boolean;
    contrastRatio: number;
  } {
    const contrast = this.getContrast(foreground, background);
    
    return {
      contrastRatio: contrast,
      wcagAA: contrast >= 4.5,
      wcagAAA: contrast >= 7
    };
  }

  // 私有辅助方法
  private static rgbFromChroma(chromaColor: chroma.Color): RGB {
    const [r, g, b] = chromaColor.rgb();
    return { r: Math.round(r), g: Math.round(g), b: Math.round(b) };
  }

  private static hslFromChroma(chromaColor: chroma.Color): HSL {
    const [h, s, l] = chromaColor.hsl();
    return { 
      h: Math.round(h || 0), 
      s: Math.round(s * 100), 
      l: Math.round(l * 100) 
    };
  }

  private static hsvFromChroma(chromaColor: chroma.Color): HSV {
    const [h, s, v] = chromaColor.hsv();
    return { 
      h: Math.round(h || 0), 
      s: Math.round(s * 100), 
      v: Math.round(v * 100) 
    };
  }
}

/**
 * 颜色名称映射 - 常用颜色的中文名称
 */
export const COLOR_NAMES: { [key: string]: string } = {
  '#FF0000': '红色',
  '#00FF00': '绿色',
  '#0000FF': '蓝色',
  '#FFFF00': '黄色',
  '#FF00FF': '洋红',
  '#00FFFF': '青色',
  '#000000': '黑色',
  '#FFFFFF': '白色',
  '#808080': '灰色',
  '#FFA500': '橙色',
  '#800080': '紫色',
  '#FFC0CB': '粉红色',
  '#A52A2A': '棕色',
  '#008000': '深绿色',
  '#000080': '深蓝色',
  '#FFD700': '金色',
  '#C0C0C0': '银色',
  '#FF6347': '番茄红',
  '#4169E1': '皇家蓝',
  '#32CD32': '青柠绿'
};

/**
 * 根据颜色值获取最接近的颜色名称
 */
export function getColorName(color: Color): string | undefined {
  const hex = color.hex.toUpperCase();
  
  // 直接匹配
  if (COLOR_NAMES[hex]) {
    return COLOR_NAMES[hex];
  }
  
  // 寻找最接近的颜色
  let minDistance = Infinity;
  let closestName: string | undefined;
  
  Object.entries(COLOR_NAMES).forEach(([colorHex, name]) => {
    const distance = chroma.deltaE(hex, colorHex);
    if (distance < minDistance && distance < 10) { // 阈值为10
      minDistance = distance;
      closestName = name;
    }
  });
  
  return closestName;
}